pkgname=xfstests
pkgver=git
pkgrel=1
url='https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git'
arch=('i386' 'x86_64' 'aarch64')
license=('GPL')
source=('https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git' 'https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git' 'https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git')
md5sums=('SKIP' 'SKIP' 'SKIP')

. $LKP_SRC/lib/tests/common.sh
. $LKP_SRC/lib/install.sh

build_install_xfstests()
{
	cd ${srcdir}/xfstests-dev || return

	# new tests will be added continuously and lead to new groups to split them.
	# print current head commit so we can check whether a specific test was introduced at the moment.
	git log --oneline -n1

	## Currently, ./configure file can't work with "--prefix" option correctly,
	## so we just use the "make" command to generate the execuable file.
	make
}

build_install_f2fs_tools()
{
	cd ${srcdir}/f2fs-tools || return
	./autogen.sh || return
	./configure || return
	make || return
	make install || return
	make install DESTDIR="${pkgdir}"
}

build_install_e2fuzz()
{
	cd ${srcdir}/e2fsprogs || return
	./configure || return
	make || return
	cp misc/e2fuzz ${pkgdir}/usr/local/sbin/
}

# Automatically generate ignore file to skip test cases which can not be enabled at present.
generate_exclude_files()
{
	benchmark_path="${pkgdir}/lkp/benchmarks/${pkgname}"

	mkdir $benchmark_path/tests/exclude

	# refer to xfstests-bld/kvm-xfstests/test-appliance/files/root/fs
	# $ ls -d */exclude
	# ext2/exclude  ext3/exclude  ext4/exclude  local/exclude  nfs/exclude  reiserfs/exclude  tmpfs/exclude
	for fs in ext2 ext4
	do
		wget --no-check-certificate -O $benchmark_path/tests/exclude/$fs https://git.kernel.org/pub/scm/fs/ext2/xfstests-bld.git/plain/test-appliance/files/root/fs/$fs/exclude || return
	done

	# In xfstests-dev/tests/generic/605 generic/606 generic/607 generic/608 mount options is "dax=always"
	# _require_scratch_dax_mountopt "dax=always"
	# ext2 do not support -o dax=always, so ignore these test cases
	cd $benchmark_path/tests
	grep "dax=always" generic -R | cut -d':' -f1 | sort -u >> $benchmark_path/tests/exclude/ext2
	cd -

	# # cifs exclude files, https://wiki.samba.org/index.php/Xfstesting-cifs
	# wget https://wiki.samba.org/images/d/db/Xfstests.exclude.very-slow.txt -O $benchmark_path/tests/cifs/exclude.very-slow.txt || return
	# wget https://wiki.samba.org/images/b/b0/Xfstests.exclude.incompatible-smb3.txt -O $benchmark_path/tests/cifs/exclude.incompatible-smb3.txt || return
	# wget https://wiki.samba.org/images/9/9f/Xfstests.exclude.incompatible-smb2.txt -O $benchmark_path/tests/cifs/exclude.incompatible-smb2.txt || return

	# # download cifs config file
	# wget https://wiki.samba.org/images/9/99/Xfstests.local.config.txt -O $benchmark_path/cifs-local.config
}

hide()
{
	mv $1 .$1
}

# collect xfs _require_xfs_stress_online_repair$
collect()
{
	local fs="$1"
	local pattern="$2"
	shift 2

	local cmd="grep -lr '$pattern' tests/$fs"

	for pattern in "$@"; do
		cmd+=" | xargs grep -l '$pattern'"
	done

	eval $cmd | cut -d/ -f3 | grep -v -f <(cat $benchmark_path/tests/$fs-*) | sort
}

pattern_to_test()
{
	local fs=$1
	local pattern="$2"

	local test=" ${pattern//\$}" # " _require_scratch_reflink _require_xfs_scratch_rmapbt"
	test="${test//require/_}" # " ___scratch_reflink ___xfs_scratch_rmapbt"
	test=$(echo "$test" | sed "s/ _*${fs}/ _/g") # " ___scratch_reflink _scratch_rmapbt"
	test=$(echo "$test" | sed 's/ _*/_/g') # _scratch_reflink_scratch_rmapbt
	test="${test//_/-}" # -scratch-reflink-scratch-rmapbt

	echo "$fs$test"
}

generate_special_require_tests()
{
	benchmark_path="${pkgdir}/lkp/benchmarks/${pkgname}"
	cd ${srcdir}/xfstests-dev || return

	for fs in generic ext4 udf ocfs2 nfs btrfs xfs overlay shared ceph f2fs perf cifs
	do
		# "006 dangerous_fuzzers" in tests/ext4/group.list => "006" in ext4-dangerous-fuzzers
		# "054 auto quick dangerous_fuzzers" in tests/ext4/group.list => "054" in ext4-dangerous-fuzzers
		grep "dangerous_fuzzers" tests/$fs/group.list | cut -d' ' -f1 > $benchmark_path/tests/$fs-dangerous-fuzzers
	done

	while read -r line; do
		[[ -z "$line" || "$line" =~ ^# ]] && continue

		local pattern="${line%%=*}"
		local fses="${line#*=}"

		for fs in $fses; do
			local test=$(pattern_to_test "$fs" "$pattern") # scratch-reflink_xfs-scratch-rmapbt

			echo "collect $fs ${pattern} as $test"
			collect "$fs" $pattern > "$benchmark_path/tests/$test"
		done
	done < "$(get_pkg_dir $pkgname)/addon/split-rules"

	# these tests require -o dax support
	for fs in generic ext4
	do
		grep "dax" tests/$fs/group.list | cut -d' ' -f1 > $benchmark_path/tests/$fs-dax
	done
}

build()
{
	benchmark_path="${pkgdir}/lkp/benchmarks/${pkgname}"
	mkdir -p ${benchmark_path}/tests

	cd $srcdir
	build_install_xfstests || return
	build_install_f2fs_tools || return
	build_install_e2fuzz
}

package()
{
	benchmark_path="${pkgdir}/lkp/benchmarks/${pkgname}"
	cp -af $srcdir/xfstests-dev/* $benchmark_path

	wget --no-check-certificate -O $benchmark_path/tools/find-api-violations.sh https://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git/plain/tools/find-api-violations.sh || return

	generate_exclude_files || return

	generate_tests || return

	split_tests
}

generate_tests()
{
	benchmark_path="${pkgdir}/lkp/benchmarks/${pkgname}"

	for tests in $(get_pkg_dir $pkgname)/addon/tests/*
	do
		cat $tests | grep -v '^#' > $benchmark_path/tests/$(basename $tests)
	done

	generate_special_require_tests || return

	# generate the new add subcase automatically after every upgrade xfstests
	cd $benchmark_path/tests

	$LKP_SRC/tools/generate-tests ext4
	$LKP_SRC/tools/generate-tests btrfs
	$LKP_SRC/tools/generate-tests xfs
	$LKP_SRC/tools/generate-tests generic
	$LKP_SRC/tools/generate-tests udf
	$LKP_SRC/tools/generate-tests ocfs2
	$LKP_SRC/tools/generate-tests cifs
}

# Some files contain too many tests, which are split for easy testing
split_tests()
{
	benchmark_path="${pkgdir}/lkp/benchmarks/${pkgname}"

	cd $benchmark_path/tests
	split_standalone_tests || return

	$LKP_SRC/tools/split-tests xfs-all 10 xfs-group-
	$LKP_SRC/tools/split-tests btrfs-all 10 btrfs-group-
	$LKP_SRC/tools/split-tests generic-all 10 generic-group-
	$LKP_SRC/tools/split-tests ext4-all 20 ext4-group-
	$LKP_SRC/tools/split-tests udf-all 10 udf-group-
	$LKP_SRC/tools/split-tests ocfs2-all 10 ocfs2-group-

	$LKP_SRC/tools/split-tests xfs-scratch-reflink 20 xfs-scratch-reflink-
	hide xfs-scratch-reflink

	$LKP_SRC/tools/split-tests generic-scratch-reflink 20 generic-scratch-reflink-
	hide generic-scratch-reflink

	$LKP_SRC/tools/split-tests generic-metadata-journaling 20 generic-metadata-journaling-
	hide generic-metadata-journaling
}

# Some special tests need to be separated and tested separately
split_standalone_tests()
{
	# These special tests are written in the relevant files under LKP-SRC/pack/xfstests-addon/tests
	for file in *-standalone
	do
		fields=(`echo $file | tr '-' ' '`)
		fs=${fields[0]}

		tests=$(cat $file)
		for test in ${tests[@]}
		do
			echo $test >> ./$fs-$test
		done
	done
}
